//希望是一个工具模块当中重写的以下方法
const utilsModule = (function (Function) {
  //外面注入的Function作为局部变量

  //用于判断类型的函数
  function typeOf(value) {
    if (value === null) {
      return "null";
    }

    //({}).toString.call(value) -> '[object Object]' -> 'Object'

    //包装类 或 对象，函数
    return typeof value === "object"
      ? {
          "[object Object]": "Object",
          "[object Array]": "Array",
          "[object Number]": "Number",
          "[object String]": "String",
          "[object Boolean]": "Boolean",
        }[{}.toString.call(value)]
      : typeof value;
  }
  
  //var test = myNew(Test, 1, 2);
  function myNew() {
    //拿到构造函数
    //[].shift.call(arguments)拿到数组里的第一个元素
    var constructor = [].shift.call(arguments),
      //过程1：this指向一个空对象
      _this = {};

      // console.log(constructor);
      //ƒ Test(a, b){...}

    //过程2：给this对象新增__proto__属性
    _this.__proto__ = constructor.prototype;

    //过程3：当实例化时this指向实例化出来的对象
    //构造函数执行后返回this指向实例化的对象
    //改变this指向为_this, 且传入参数列表
    const res = constructor.apply(_this, arguments);

    // console.log(_this);
    //Test {a: 1, b: 2}

    //返回定义好的this对象(实例化后的对象)
    //存在用户执行完构造函数时自定义返回值的情况：
    //情况1：定义的返回值是对象时，返回用户定义的对象
    //情况2：定义的返回值不是对象时，返回定义好的this对象
    return  typeOf(res) === 'Object' ? res : _this;
  }

  return {
    myNew,
    typeOf
  };
})(Function);

export default utilsModule;
